import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import dayjs from 'dayjs';
import * as echarts from 'echarts';
import Echarts from '@kuiper-components/echarts';
import Helper from '../../../../components/Helper';

import {
	SECURITY_EVENT_TYPE_MAP,
	VUL_LEVEL_NUM_EN_MAP,
} from '../../../../../common/constants';
import { datetime } from '../../../../../common/formatter';
import ChartTitle from '../../../../components/ChartTitle';
import RadioButton from '../../../../components/RadioButton';
import s from './TrendChart.module.css';

const EVENT_CATE_MAP = {
	all: '全部',
	high: '高危',
	medium: '中危',
	low: '低危',
};

const emptyLineData = [];
for (let i = 7; i >= 1; i--) {
	emptyLineData.push([
		dayjs().subtract(i, 'days').startOf('day').toDate(),
		0,
		0,
		0,
		0,
		0,
	]);
}

const numFormat = e => {
	let res = null
	try {
		res = new Intl.NumberFormat('en-US').format(e)
	} catch {
		res = e.toLocaleString('en-US')
	}
	return isNaN(e) ? 0 : res;
};

export default function TrendChart({ className, tasks, detectTime, dateRask, jobId }) {
	const [status, setStatus] = React.useState('all');
	const [myChart, setChart] = React.useState(undefined);
	const initLineData = React.useMemo(() => {
		return [...tasks].reverse().reduce(
			(obj, task) => {
				const warnings = task?.result?.warnings || [];
				const info = warnings.reduce(
					(res, w) => {
						res.all.total++;
						res.all[w?.category]++;
						res[VUL_LEVEL_NUM_EN_MAP[w?.level]].total++;
						res[VUL_LEVEL_NUM_EN_MAP[w?.level]][w?.category]++;

						return res;
					},
					Object.keys(EVENT_CATE_MAP).reduce((obj, key) => {
						obj[key] = Object.keys(SECURITY_EVENT_TYPE_MAP).reduce(
							(obj, key) => {
								obj[key] = 0;
								return obj;
							},
							{ total: 0 }
						);
						return obj;
					}, {})
				);
				Object.keys(EVENT_CATE_MAP).forEach(event => {
					obj[event].push([
						new Date(task?.endTime),
						info[event]?.total,
						info[event].black_links,
						info[event].cryjack,
						info[event].malscan,
						info[event].broken_links,
						info[event].foreign_links,
					]);
				});
				return obj;
			},
			Object.keys(EVENT_CATE_MAP).reduce((obj, key) => {
				obj[key] = [];
				return obj;
			}, {})
		);
	}, [tasks, detectTime]);

	const lineOption = {
		tooltip: {
			trigger: 'axis',
			axisPointer: {
				type: 'cross',
			},
			formatter([{ data, seriesName }]) {
				return `<div >
										<div style="border-bottom: 1px solid var(--color-border-2);padding: 0.5rem 1.25rem;">
											${datetime(data[0])}
										</div>
										<div>
										<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">风险URL总数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[1]
												)}个</div>
											</div>
										<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">含暗链URL数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[2]
												)}个</div>
											</div>
											<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">含挂马URL数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[4]
												)}个
												</div>
											</div>
											<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">含挖矿URL数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[3]
												)}个
												</div>
											</div>
											<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">含坏链URL数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[5]
												)}个
												</div>
											</div>
											<div style="display: flex; padding: 0.5rem 1.25rem;">
												<div style="width: 4rem">含风险外链数</div>
												<div style="width: 3rem;text-align: right;margin-left:1.25rem;">${numFormat(
													data[6]
												)}个
												</div>
											</div>
										 </div>
									</div>`;
			},
			backgroundColor: '#fff',
			textStyle: '#696C78',
			extraCssText:
				'width: 10rem;color: var(--color-text-1);line-height:1rem;margin: 0 auto;',
		},
		grid: {
			left: '60',
			right: '110',
			top: '50',
			bottom: '35',
		},
		axisPointer: {
			show: true,
			lineStyle: {
				width: 2,
				type: 'dotted',
				color: '#F0443C',
			},
		},
		xAxis: {
			type: 'time',
			boundaryGap: false,
			splitNumber: 7,
			splitLine: { show: false },
			axisLine: { lineStyle: { color: 'transparent' }, show: false },
			axisTick: {
				show: false,
			},
			axisLabel: {
				formatter(value) {
					const date = new Date(value);
					return datetime(date, 'YYYY-MM-DD HH:mm:ss');
				},
				showMaxLabel: false,
				margin: 20,
				align: 'left',
			},
		},
		yAxis: {
			type: 'value',
			boundaryGap: false,
			axisTick: {
				show: false,
			},
			axisLine: { lineStyle: { color: 'transparent' } },
			splitLine: { lineStyle: { color: '#F7F9FC' } },
		},
		textStyle: { color: '#696C78', fontSize: 12 },
		series: [
			{
				data: [],
				name: '全部',
				type: 'line',
				smooth: true,
				smoothMonotone: 'x',
				showSymbol: false,
				lineStyle: {
					color: '#FAAF2C',
					width: 2,
				},
				areaStyle: {
					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
						{
							offset: 0,
							color: 'rgba(255, 165, 78, 0.4977)',
						},
						{
							offset: 1,
							color: 'rgba(249, 222, 105, 0.08)',
						},
					]),
				},
			},
		],
	};

	let lineData = initLineData[status];

	let highLightIdx = -1;

	if (detectTime) {
		highLightIdx =
			detectTime === 'last' ? lineData.length - 1 : lineData.length - 2;
	}
	if (highLightIdx > -1 && detectTime !== 'range') {
		lineOption.series[0].markPoint = {
			label: {
				formatter: `${detectTime === 'last' ? '最新一次监测' : '上次监测'}`,
				position: 'top',
			},
			data: [{ coord: lineData[highLightIdx] }],
			symbolSize: 24,
			itemStyle: {
				color: '#FAAF2C',
			},
		};
	} else {
		lineOption.series[0].markPoint = {};
	}
	if (lineData.length === 0) {
		lineData = JSON.parse(JSON.stringify(emptyLineData))
		lineOption.tooltip.show = false
		lineOption.axisPointer.show = false
		lineOption.series[0].lineStyle.width = 0
		lineOption.yAxis.splitNumber = 5
		lineOption.yAxis.max = 5
		lineOption.yAxis.min = 0
	}
	lineOption.series[0].data = lineData;

	if (lineData.length === 0 && dateRask.dateRange) {
		lineOption.series[0].data = [
			[Date.parse(dateRask.dateRange[0]), 0, {}],
			[Date.parse(dateRask.dateRange[1]), 0, {}],
		];
		lineOption.series[0].lineStyle = {
			width: 0,
		};
		lineOption.axisPointer.lineStyle = {
			type: 'dotted',
			width: 0,
		};
	}
	const getChart = e => {
		setChart(e);
	};

	if (myChart) {
		myChart.clear()
		myChart.setOption(lineOption);
	}

	return (
		<div className={cn(className, s.trendChart)}>
			<div className={s.header}>
				<ChartTitle>
					安全事件监测趋势
					<Helper overlay="按风险URL统计" placement="top" />
				</ChartTitle>
				<div className={s.levelSelect}>
					{Object.entries(EVENT_CATE_MAP).map(([value, label]) => (
						<RadioButton
							key={value}
							onChecked={() => setStatus(value)}
							checked={status === value}
							className={s.radio}
						>
							{label}
						</RadioButton>
					))}
				</div>
			</div>
			<Echarts
				key={status}
				getInstance={getChart}
				className={s.chart}
				option={lineOption}
			/>
		</div>
	);
}

TrendChart.propTypes = {
	className: PropTypes.string,
	tasks: PropTypes.arrayOf(
		PropTypes.shape({
			_id: PropTypes.string,
			target: PropTypes.string,
			result: PropTypes.object,
			// warningCount: PropTypes.number,
		})
	),
	detectTime: PropTypes.string,
	dateRask: PropTypes.array,
};

TrendChart.defaultProps = {
	className: s.trendChart,
	tasks: [],
};
